import prisma from "../prisma/prismaClient.js";
import Prisma from "@prisma/client";
// 创建文件
const createFile = (data) => prisma.file.create({ data });

//获取文件总数和文件增加数
const getFileIncreaseInfo = async () => {
  const todayStart = new Date();
  todayStart.setHours(0, 0, 0, 0);

  const total = await prisma.file.count()
  const today = await prisma.file.count({
    where: {
      createdAt: {
        gte: todayStart
      }
    }
  })
  return {
    total,
    today
  }
}

const getRecentDaysFiles = async (days = 7) => {
  const results = [];
  const today = new Date();

  for (let i = days - 1; i >= 0; i--) {
    const date = new Date(today);
    date.setDate(date.getDate() - i);

    const startOfDay = new Date(date);
    startOfDay.setHours(0, 0, 0, 0);

    const endOfDay = new Date(date);
    endOfDay.setHours(23, 59, 59, 999);

    const count = await prisma.file.count({
      where: {
        createdAt: {
          gte: startOfDay,
          lte: endOfDay
        },
        type: { not: "folder" }
      }
    });

    results.push({
      date: date.toISOString().split('T')[0],
      count
    });
  }

  return results;
};


// 获取单个文件
const getFileById = (fileId) => {
  return prisma.file.findUnique({
    where: { id: fileId },
    include: {
      parent: {
        select: { id: true, filename: true, parentId: true },
      },
    },
  });
};

//获取单个文件
const getFileInfoById = (fileId) => {
  return prisma.file.findUnique({
    where: { id: fileId },
    include: {
      parent: {
        select: {
          id: true,
          filename: true,
          parent: {
            select: {
              id: true,
              filename: true,
              parent: {
                select: {
                  id: true,
                  filename: true,
                  parentId: true,
                },
              },
            },
          },
        },
      },
    },
  });
}

// 获取子文件夹
const getChildren = (userId, parentId) => {
  return prisma.file.findMany({
    where: { userId, parentId, isDeleted: false, isFolder: true },
    select: { id: true, filename: true, isFolder: true },
  });
};

// 更新文件信息
const updateFile = (id, updateData) => {
  return prisma.file.updateMany({
    where: {
      id,
    },
    data: updateData,
  });
};

// 批量更新文件信息
const updateFiles = (fileIds, updateData) => {
  return prisma.file.updateMany({
    where: { id: { in: fileIds } },
    data: updateData,
  });
};

// isDeleted 为 true 时，获取删除了的文件和文件夹的信息 
// isDeleted 为 false 时，获取未删除的文件和文件夹的信息
const getDescendantInfos = async (fileIds, userId, isDeleted) => {
  return await prisma.$transaction(
    async (tx) => {
      const items = await tx.file.findMany({
        where: { id: { in: fileIds }, isDeleted, userId },
        select: { id: true, isFolder: true, size: true },
      });

      if (items.length === 0) return { Ids: [], totalSize: 0 };
      if (items.length !== fileIds.length) {
        console.error("部分文件不存在或无权操作");
      }

      const folderIds = items.filter((i) => i.isFolder).map((f) => f.id);
      let allDescendants = [];

      if (folderIds.length > 0) {
        allDescendants = await tx.$queryRaw`
          WITH RECURSIVE descendant_files AS (
            SELECT id, size FROM File 
            WHERE parentId IN (${Prisma.join(folderIds)}) AND isDeleted = ${isDeleted}
            UNION ALL
            SELECT f.id, f.size FROM File f
            JOIN descendant_files df ON f.parentId = df.id
            WHERE f.isDeleted = ${isDeleted}
          )
          SELECT id, size FROM descendant_files
        `;
      }

      const Ids = [...new Set([...fileIds, ...allDescendants.map((d) => d.id)])];
      const totalSize = [...items, ...allDescendants].reduce(
        (sum, file) => sum + (Number(file.size) || 0),
        0
      );

      return { Ids, totalSize };
    },
    { isolationLevel: "Serializable" }
  );
};

// 清除文件
const deleteFile = (fileId) => prisma.file.delete({ where: { id: fileId } });

// 批量清除文件
const deleteFiles = (fileIds, userId) =>
  prisma.file.deleteMany({ where: { id: { in: fileIds }, userId } });

//获取指定用户下的文件和文件夹列表
const getFilePage = async (
  userId,
  parentId = null,
  pageSize = 10,
  current = 1,
  searchText = "",
  sortField = "",
  sortOrder = "",
) => {
  pageSize = Number(pageSize);
  current = Number(current);
  const whereClause = {
    userId,
    parentId,
    isDeleted: false,
  };

  if (searchText) {
    whereClause.filename = {
      contains: searchText,
    };
  }

  const validSortFields = ["size", "filename", "createdAt", "updatedAt"];
  let orderBy = { ["sort"]: "asc" }; // 默认排序字段和顺序
  if (sortField && validSortFields.includes(sortField) && sortOrder) {
    orderBy = { [sortField]: sortOrder === "ascending" ? "asc" : "desc" };
  }

  const files = await prisma.file.findMany({
    where: whereClause,
    skip: (current - 1) * pageSize,
    take: Number(pageSize),
    orderBy,
  });

  const total = await prisma.file.count({
    where: {
      userId,
      parentId,
      isDeleted: false,
    },
  });
  const generatePath = (file) => {
    if (!file.parent) return file.filename;
    return `${generatePath(file.parent)}/${file.filename}`;
  };
  const enhancedFiles = files.map((file) => ({
    ...file,
    path: generatePath(file),
  }));

  return { list: enhancedFiles, total };
};

// 获取回收站文件列表
const getRecycle = () => {
  return prisma.file.findMany({
    where: {
      isDeleted: true,
      // 父文件夹未被删除，或者没有父文件夹
      OR: [{ parent: { isDeleted: false } }, { parentId: null }],
    },
    orderBy: { ["sort"]: "desc" }
  });
};

const getIdsFile = (ids) => {
  return prisma.file.findMany({
    where: { id: { in: ids } }
  })
}

const checkFilename = async (userId, parentId, filename) => {
  return await prisma.file.findFirst({
    where: { userId, parentId, filename, isDeleted: false },
  });
}

const getFileProperty = async () => {
  const result = await prisma.file.groupBy({
    by: ['sort'],
    where: {
      isDeleted: false,
      sort: { not: 0 }
    },
    _sum: {
      size: true
    },
    orderBy: {
      sort: 'asc'
    }
  });
  return result.map(item => ({ name: item.sort, value: item._sum.size?.toString() || '0' }))
};

export default {
  createFile,
  getFileById,
  updateFile,
  updateFiles,
  deleteFile,
  deleteFiles,
  getFilePage,
  getChildren,
  getRecycle,
  getDescendantInfos,
  getIdsFile,
  checkFilename,
  getFileInfoById,
  getFileIncreaseInfo,
  getRecentDaysFiles,
  getFileProperty
};
